package com.copc.common.util;

import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * 抖音工具类
 */
public class BytedancePayVerifyUtil {
    /**
     * 校验签名
     * @param httpBody
     * @param publicKey
     * @param signStr
     * @param timestamp
     * @param nonce
     * @return
     * @throws Exception
     */
    public static boolean verify(String httpBody, String publicKey, String signStr, Long timestamp, String nonce) throws Exception {
        StringBuffer buffer = new StringBuffer();
        buffer.append(timestamp).append("\n");
        buffer.append(nonce).append("\n");
        buffer.append(httpBody).append("\n");
        String message = buffer.toString();
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initVerify(string2PublicKey(publicKey));
        sign.update(message.getBytes(StandardCharsets.UTF_8));
        return sign.verify(Base64.getDecoder().decode(signStr.getBytes(StandardCharsets.UTF_8)));
    }

    public static PublicKey string2PublicKey(String publicKey) throws Exception{
        byte[] decoded = Base64.getDecoder().decode(publicKey);
        return KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
    }

    /**
     * 获取签名
     * @param privateKeyStr
     * @param method
     * @param uri
     * @param timestamp
     * @param nonce
     * @param body
     * @return
     * @throws Exception
     */
    public static String getSignature(String privateKeyStr, String method, String uri, long timestamp, String nonce, String body) throws Exception {
        //method内容必须大写，如GET、POST，uri不包含域名，必须以'/'开头
        String rawStr = method + "\n" +
                uri + "\n" +
                timestamp + "\n" +
                nonce + "\n" +
                body + "\n";
        Signature sign = Signature.getInstance("SHA256withRSA");
        sign.initSign(string2PrivateKey(privateKeyStr));
        sign.update(rawStr.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(sign.sign());
    }

    public static PrivateKey string2PrivateKey(String privateKeyStr) {
        PrivateKey prvKey = null;
        try {
            byte[] privateBytes = Base64.getDecoder().decode(privateKeyStr);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            prvKey = keyFactory.generatePrivate(keySpec);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return prvKey;
    }

}
